﻿using System;
using System.Threading;

namespace KuiHuaBaoDian.Services.Asset {

    /// <summary>
    /// 资产加载请求
    /// </summary>
    public static class AssetRequest {

        /// <summary>
        /// 实例化
        /// </summary>
        /// <param name="key">资产Key</param>
        /// <returns>资产加载请求实例</returns>
        public static IAssetRequest Instantiate(string key) => Instantiate(key, CancellationToken.None, null, false);

        /// <summary>
        /// 实例化
        /// </summary>
        /// <param name="key">资产Key</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>资产加载请求实例</returns>
        public static IAssetRequest Instantiate(string key, CancellationToken cancellationToken) => Instantiate(key, cancellationToken, null, false);

        /// <summary>
        ///  实例化
        /// </summary>
        /// <param name="key">资产Key</param>
        /// <param name="downloadProgress">下载进度</param>
        /// <returns>资产加载请求实例</returns>
        public static IAssetRequest Instantiate(string key, IAssetDownloadProgress downloadProgress) => Instantiate(key, CancellationToken.None, downloadProgress, false);

        /// <summary>
        /// 实例化
        /// </summary>
        /// <param name="key">资产Key</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <param name="downloadProgress">下载进度</param>
        /// <param name="ignoreFailureLog">忽略失败Log</param>
        /// <returns>资产加载请求实例</returns>
        public static IAssetRequest Instantiate(string key, CancellationToken cancellationToken, IAssetDownloadProgress downloadProgress, bool ignoreFailureLog) {
            var instance = KHBD.TypeMap.Instantiate<IAssetRequest>();
            (instance as IAssetRequest.IInitializable).Initialize(key, cancellationToken, downloadProgress, ignoreFailureLog);
            return instance;
        }
    }

    /// <summary>
    /// 资产加载请求
    /// </summary>
    public interface IAssetRequest {

        /// <summary>
        /// 初始化独立写接口
        /// </summary>
        public interface IInitializable {

            /// <summary>
            /// 初始化
            /// </summary>
            /// <param name="key">资产Key</param>
            /// <param name="cancellationToken">取消令牌</param>
            /// <param name="downloadProgress">下载进度</param>
            /// <param name="ignoreFailureLog">忽略失败Log</param>
            void Initialize(string key, CancellationToken cancellationToken, IAssetDownloadProgress downloadProgress, bool ignoreFailureLog);
        }

        /// <summary>
        /// 资产Key
        /// </summary>
        string Key { get; }

        /// <summary>
        /// 取消令牌
        /// </summary>
        CancellationToken CancellationToken { get; }

        /// <summary>
        /// 下载进度
        /// </summary>
        IAssetDownloadProgress DownloadProgress { get; }

        /// <summary>
        /// 忽略失败Log
        /// </summary>
        bool IgnoreFailureLog { get; }
    }

    [Implement(typeof(IAssetRequest))]
    internal sealed class KHBD_AssetRequest : KHBD_PoolObject, IAssetRequest, IAssetRequest.IInitializable {

        public string Key { get; private set; }

        public CancellationToken CancellationToken { get; private set; }

        public IAssetDownloadProgress DownloadProgress { get; private set; }

        public bool IgnoreFailureLog { get; private set; }

        void IAssetRequest.IInitializable.Initialize(string key, CancellationToken cancellationToken, IAssetDownloadProgress downloadProgress, bool ignoreFailureLog) {
            Key = key;
            CancellationToken = cancellationToken;
            DownloadProgress = downloadProgress;
            IgnoreFailureLog = ignoreFailureLog;
        }

        protected override void Allocate() {
        }

        protected override void Release() {
            DownloadProgress = null;
            CancellationToken = default;
            Key = null;
            IgnoreFailureLog = false;
        }
    }
}
